.globl write_matrix

.text
# ==============================================================================
# FUNCTION: Writes a matrix of integers into a binary file
# FILE FORMAT:
#   The first 8 bytes of the file will be two 4 byte ints representing the
#   numbers of rows and columns respectively. Every 4 bytes thereafter is an
#   element of the matrix in row-major order.
# Arguments:
#   a0 (char*) is the pointer to string representing the filename
#   a1 (int*)  is the pointer to the start of the matrix in memory
#   a2 (int)   is the number of rows in the matrix
#   a3 (int)   is the number of columns in the matrix
# Returns:
#   None
# Exceptions:
#   - If you receive an fopen error or eof,
#     this function terminates the program with error code 27
#   - If you receive an fclose error or eof,
#     this function terminates the program with error code 28
#   - If you receive an fwrite error or eof,
#     this function terminates the program with error code 30
# ==============================================================================
write_matrix:
	# Prologue
    addi sp, sp, -12
    sw ra, 0(sp)
    sw s1, 4(sp)
    sw s2, 8(sp)
        
    # fopen
    addi sp, sp, -12
    sw a1, 0(sp)
    sw a2, 4(sp)
    sw a3, 8(sp)
    li a1, 1 # write only
    jal ra, fopen
    li t0, -1
    beq a0, t0, fopen_error
    mv s1, a0 # file descriptor
    lw a1, 0(sp)
    lw a2, 4(sp)
    lw a3, 8(sp)
    addi sp, sp, 12
        
    # fwrite rows cols
    addi sp, sp, -16
    sw a1, 0(sp)
    sw a2, 4(sp)
    sw a3, 8(sp)
    sw t0, 12(sp)
    mv a0, s1 # file descriptor
    addi a1, sp, 4
    li a2, 2
    li a3, 4
    mv s2, a2
    jal ra, fwrite
    bne a0, s2, fwrite_error
    lw a1, 0(sp)
    lw a2, 4(sp)
    lw a3, 8(sp)
    lw t0, 12(sp)
    addi sp, sp, 16
    
    # fwrite matrix
    addi sp, sp, -4
    sw t0, 0(sp)
    mv a0, s1
    mul a2, a2, a3
    mv s2, a2
    li a3, 4
    jal ra, fwrite
    bne a0, s2, fwrite_error
    lw t0, 0(sp)
    addi sp, sp, 4
    
    # fclose
    addi sp, sp, -4
    sw t0, 0(sp)
    mv a0, s1
    jal ra, fclose
    lw t0, 0(sp)
    addi sp, sp, 4
    beq a0, t0, fclose_error
    
	# Epilogue
    lw ra, 0(sp)
    lw s1, 4(sp)
    lw s2, 8(sp)
    addi sp, sp, 12
	ret
fopen_error:
    li a0, 27
    j exit
fclose_error:
    li a0, 28
    j exit
fwrite_error:
    li a0, 30
    j exit